// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Code generated by sidekick. DO NOT EDIT.

use crate::Result;
#[allow(unused_imports)]
use gax::error::Error;

const DEFAULT_HOST: &str = "https://storage.googleapis.com";

mod info {
    const NAME: &str = env!("CARGO_PKG_NAME");
    const VERSION: &str = env!("CARGO_PKG_VERSION");
    lazy_static::lazy_static! {
        pub(crate) static ref X_GOOG_API_CLIENT_HEADER: String = {
            let ac = gaxi::api_header::XGoogApiClient{
                name:          NAME,
                version:       VERSION,
                library_type:  gaxi::api_header::GAPIC,
            };
            ac.grpc_header_value()
        };
    }
}

/// Implements [StorageControl](super::stub::StorageControl) using a Tonic-generated client.
#[derive(Clone)]
pub struct StorageControl {
    inner: gaxi::grpc::Client,
}

impl std::fmt::Debug for StorageControl {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        f.debug_struct("StorageControl")
            .field("inner", &self.inner)
            .finish()
    }
}

impl StorageControl {
    pub async fn new(config: gaxi::options::ClientConfig) -> gax::client_builder::Result<Self> {
        let inner = gaxi::grpc::Client::new(config, DEFAULT_HOST).await?;
        Ok(Self { inner })
    }
}

impl super::stub::StorageControl for StorageControl {
    async fn delete_bucket(
        &self,
        req: crate::model::DeleteBucketRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<()>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.storage.v2.Storage",
                "DeleteBucket",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.storage.v2.Storage/DeleteBucket");
        let x_goog_request_params = {
            use gaxi::routing_parameter::Segment;
            gaxi::routing_parameter::format(&[None
                .or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req).map(|m| &m.name).map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("bucket", v))])
        };
        if x_goog_request_params.is_empty() {
            use gax::error::binding::BindingError;
            use gaxi::path_parameter::PathMismatchBuilder;
            use gaxi::routing_parameter::Segment;
            let mut paths = Vec::new();
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req).map(|m| &m.name).map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "name",
                    "**",
                );
                paths.push(builder.build());
            }
            return Err(gax::error::Error::binding(BindingError { paths }));
        }

        type TR = ();
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, ()>)
    }

    async fn get_bucket(
        &self,
        req: crate::model::GetBucketRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<crate::model::Bucket>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.storage.v2.Storage",
                "GetBucket",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.storage.v2.Storage/GetBucket");
        let x_goog_request_params = {
            use gaxi::routing_parameter::Segment;
            gaxi::routing_parameter::format(&[None
                .or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req).map(|m| &m.name).map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("bucket", v))])
        };
        if x_goog_request_params.is_empty() {
            use gax::error::binding::BindingError;
            use gaxi::path_parameter::PathMismatchBuilder;
            use gaxi::routing_parameter::Segment;
            let mut paths = Vec::new();
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req).map(|m| &m.name).map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "name",
                    "**",
                );
                paths.push(builder.build());
            }
            return Err(gax::error::Error::binding(BindingError { paths }));
        }

        type TR = crate::google::storage::v2::Bucket;
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, crate::model::Bucket>)
    }

    async fn create_bucket(
        &self,
        req: crate::model::CreateBucketRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<crate::model::Bucket>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.storage.v2.Storage",
                "CreateBucket",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.storage.v2.Storage/CreateBucket");
        let x_goog_request_params = {
            use gaxi::routing_parameter::Segment;
            gaxi::routing_parameter::format(&[None
                .or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req)
                            .and_then(|m| m.bucket.as_ref())
                            .map(|m| &m.project)
                            .map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req).map(|m| &m.parent).map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("project", v))])
        };
        if x_goog_request_params.is_empty() {
            use gax::error::binding::BindingError;
            use gaxi::path_parameter::PathMismatchBuilder;
            use gaxi::routing_parameter::Segment;
            let mut paths = Vec::new();
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req)
                        .and_then(|m| m.bucket.as_ref())
                        .map(|m| &m.project)
                        .map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "bucket.project",
                    "**",
                );
                paths.push(builder.build());
            }
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req).map(|m| &m.parent).map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "parent",
                    "**",
                );
                paths.push(builder.build());
            }
            return Err(gax::error::Error::binding(BindingError { paths }));
        }

        type TR = crate::google::storage::v2::Bucket;
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, crate::model::Bucket>)
    }

    async fn list_buckets(
        &self,
        req: crate::model::ListBucketsRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<crate::model::ListBucketsResponse>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.storage.v2.Storage",
                "ListBuckets",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.storage.v2.Storage/ListBuckets");
        let x_goog_request_params = {
            use gaxi::routing_parameter::Segment;
            gaxi::routing_parameter::format(&[None
                .or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req).map(|m| &m.parent).map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("project", v))])
        };
        if x_goog_request_params.is_empty() {
            use gax::error::binding::BindingError;
            use gaxi::path_parameter::PathMismatchBuilder;
            use gaxi::routing_parameter::Segment;
            let mut paths = Vec::new();
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req).map(|m| &m.parent).map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "parent",
                    "**",
                );
                paths.push(builder.build());
            }
            return Err(gax::error::Error::binding(BindingError { paths }));
        }

        type TR = crate::google::storage::v2::ListBucketsResponse;
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, crate::model::ListBucketsResponse>)
    }

    async fn lock_bucket_retention_policy(
        &self,
        req: crate::model::LockBucketRetentionPolicyRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<crate::model::Bucket>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.storage.v2.Storage",
                "LockBucketRetentionPolicy",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static(
            "/google.storage.v2.Storage/LockBucketRetentionPolicy",
        );
        let x_goog_request_params = {
            use gaxi::routing_parameter::Segment;
            gaxi::routing_parameter::format(&[None
                .or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req).map(|m| &m.bucket).map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("bucket", v))])
        };
        if x_goog_request_params.is_empty() {
            use gax::error::binding::BindingError;
            use gaxi::path_parameter::PathMismatchBuilder;
            use gaxi::routing_parameter::Segment;
            let mut paths = Vec::new();
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req).map(|m| &m.bucket).map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "bucket",
                    "**",
                );
                paths.push(builder.build());
            }
            return Err(gax::error::Error::binding(BindingError { paths }));
        }

        type TR = crate::google::storage::v2::Bucket;
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, crate::model::Bucket>)
    }

    async fn update_bucket(
        &self,
        req: crate::model::UpdateBucketRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<crate::model::Bucket>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.storage.v2.Storage",
                "UpdateBucket",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.storage.v2.Storage/UpdateBucket");
        let x_goog_request_params = {
            use gaxi::routing_parameter::Segment;
            gaxi::routing_parameter::format(&[None
                .or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req)
                            .and_then(|m| m.bucket.as_ref())
                            .map(|m| &m.name)
                            .map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("bucket", v))])
        };
        if x_goog_request_params.is_empty() {
            use gax::error::binding::BindingError;
            use gaxi::path_parameter::PathMismatchBuilder;
            use gaxi::routing_parameter::Segment;
            let mut paths = Vec::new();
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req)
                        .and_then(|m| m.bucket.as_ref())
                        .map(|m| &m.name)
                        .map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "bucket.name",
                    "**",
                );
                paths.push(builder.build());
            }
            return Err(gax::error::Error::binding(BindingError { paths }));
        }

        type TR = crate::google::storage::v2::Bucket;
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, crate::model::Bucket>)
    }

    async fn compose_object(
        &self,
        req: crate::model::ComposeObjectRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<crate::model::Object>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.storage.v2.Storage",
                "ComposeObject",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.storage.v2.Storage/ComposeObject");
        let x_goog_request_params = {
            use gaxi::routing_parameter::Segment;
            gaxi::routing_parameter::format(&[None
                .or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req)
                            .and_then(|m| m.destination.as_ref())
                            .map(|m| &m.bucket)
                            .map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("bucket", v))])
        };
        if x_goog_request_params.is_empty() {
            use gax::error::binding::BindingError;
            use gaxi::path_parameter::PathMismatchBuilder;
            use gaxi::routing_parameter::Segment;
            let mut paths = Vec::new();
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req)
                        .and_then(|m| m.destination.as_ref())
                        .map(|m| &m.bucket)
                        .map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "destination.bucket",
                    "**",
                );
                paths.push(builder.build());
            }
            return Err(gax::error::Error::binding(BindingError { paths }));
        }

        type TR = crate::google::storage::v2::Object;
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, crate::model::Object>)
    }

    async fn delete_object(
        &self,
        req: crate::model::DeleteObjectRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<()>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.storage.v2.Storage",
                "DeleteObject",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.storage.v2.Storage/DeleteObject");
        let x_goog_request_params = {
            use gaxi::routing_parameter::Segment;
            gaxi::routing_parameter::format(&[None
                .or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req).map(|m| &m.bucket).map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("bucket", v))])
        };
        if x_goog_request_params.is_empty() {
            use gax::error::binding::BindingError;
            use gaxi::path_parameter::PathMismatchBuilder;
            use gaxi::routing_parameter::Segment;
            let mut paths = Vec::new();
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req).map(|m| &m.bucket).map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "bucket",
                    "**",
                );
                paths.push(builder.build());
            }
            return Err(gax::error::Error::binding(BindingError { paths }));
        }

        type TR = ();
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, ()>)
    }

    async fn restore_object(
        &self,
        req: crate::model::RestoreObjectRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<crate::model::Object>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.storage.v2.Storage",
                "RestoreObject",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.storage.v2.Storage/RestoreObject");
        let x_goog_request_params = {
            use gaxi::routing_parameter::Segment;
            gaxi::routing_parameter::format(&[None
                .or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req).map(|m| &m.bucket).map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("bucket", v))])
        };
        if x_goog_request_params.is_empty() {
            use gax::error::binding::BindingError;
            use gaxi::path_parameter::PathMismatchBuilder;
            use gaxi::routing_parameter::Segment;
            let mut paths = Vec::new();
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req).map(|m| &m.bucket).map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "bucket",
                    "**",
                );
                paths.push(builder.build());
            }
            return Err(gax::error::Error::binding(BindingError { paths }));
        }

        type TR = crate::google::storage::v2::Object;
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, crate::model::Object>)
    }

    async fn get_object(
        &self,
        req: crate::model::GetObjectRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<crate::model::Object>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.storage.v2.Storage",
                "GetObject",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.storage.v2.Storage/GetObject");
        let x_goog_request_params = {
            use gaxi::routing_parameter::Segment;
            gaxi::routing_parameter::format(&[None
                .or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req).map(|m| &m.bucket).map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("bucket", v))])
        };
        if x_goog_request_params.is_empty() {
            use gax::error::binding::BindingError;
            use gaxi::path_parameter::PathMismatchBuilder;
            use gaxi::routing_parameter::Segment;
            let mut paths = Vec::new();
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req).map(|m| &m.bucket).map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "bucket",
                    "**",
                );
                paths.push(builder.build());
            }
            return Err(gax::error::Error::binding(BindingError { paths }));
        }

        type TR = crate::google::storage::v2::Object;
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, crate::model::Object>)
    }

    async fn update_object(
        &self,
        req: crate::model::UpdateObjectRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<crate::model::Object>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.storage.v2.Storage",
                "UpdateObject",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.storage.v2.Storage/UpdateObject");
        let x_goog_request_params = {
            use gaxi::routing_parameter::Segment;
            gaxi::routing_parameter::format(&[None
                .or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req)
                            .and_then(|m| m.object.as_ref())
                            .map(|m| &m.bucket)
                            .map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("bucket", v))])
        };
        if x_goog_request_params.is_empty() {
            use gax::error::binding::BindingError;
            use gaxi::path_parameter::PathMismatchBuilder;
            use gaxi::routing_parameter::Segment;
            let mut paths = Vec::new();
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req)
                        .and_then(|m| m.object.as_ref())
                        .map(|m| &m.bucket)
                        .map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "object.bucket",
                    "**",
                );
                paths.push(builder.build());
            }
            return Err(gax::error::Error::binding(BindingError { paths }));
        }

        type TR = crate::google::storage::v2::Object;
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, crate::model::Object>)
    }

    async fn list_objects(
        &self,
        req: crate::model::ListObjectsRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<crate::model::ListObjectsResponse>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.storage.v2.Storage",
                "ListObjects",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.storage.v2.Storage/ListObjects");
        let x_goog_request_params = {
            use gaxi::routing_parameter::Segment;
            gaxi::routing_parameter::format(&[None
                .or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req).map(|m| &m.parent).map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("bucket", v))])
        };
        if x_goog_request_params.is_empty() {
            use gax::error::binding::BindingError;
            use gaxi::path_parameter::PathMismatchBuilder;
            use gaxi::routing_parameter::Segment;
            let mut paths = Vec::new();
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req).map(|m| &m.parent).map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "parent",
                    "**",
                );
                paths.push(builder.build());
            }
            return Err(gax::error::Error::binding(BindingError { paths }));
        }

        type TR = crate::google::storage::v2::ListObjectsResponse;
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, crate::model::ListObjectsResponse>)
    }

    async fn rewrite_object(
        &self,
        req: crate::model::RewriteObjectRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<crate::model::RewriteResponse>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.storage.v2.Storage",
                "RewriteObject",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.storage.v2.Storage/RewriteObject");
        let x_goog_request_params = {
            use gaxi::routing_parameter::Segment;
            gaxi::routing_parameter::format(&[
                None.or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req)
                            .map(|m| &m.destination_bucket)
                            .map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("bucket", v)),
                None.or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req).map(|m| &m.source_bucket).map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("source_bucket", v)),
            ])
        };
        if x_goog_request_params.is_empty() {
            use gax::error::binding::BindingError;
            use gaxi::path_parameter::PathMismatchBuilder;
            use gaxi::routing_parameter::Segment;
            let mut paths = Vec::new();
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req)
                        .map(|m| &m.destination_bucket)
                        .map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "destination_bucket",
                    "**",
                );
                let builder = builder.maybe_add(
                    Some(&req).map(|m| &m.source_bucket).map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "source_bucket",
                    "**",
                );
                paths.push(builder.build());
            }
            return Err(gax::error::Error::binding(BindingError { paths }));
        }

        type TR = crate::google::storage::v2::RewriteResponse;
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, crate::model::RewriteResponse>)
    }

    async fn move_object(
        &self,
        req: crate::model::MoveObjectRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<crate::model::Object>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.storage.v2.Storage",
                "MoveObject",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.storage.v2.Storage/MoveObject");
        let x_goog_request_params = {
            use gaxi::routing_parameter::Segment;
            gaxi::routing_parameter::format(&[None
                .or_else(|| {
                    gaxi::routing_parameter::value(
                        Some(&req).map(|m| &m.bucket).map(|s| s.as_str()),
                        &[],
                        &[Segment::MultiWildcard],
                        &[],
                    )
                })
                .map(|v| ("bucket", v))])
        };
        if x_goog_request_params.is_empty() {
            use gax::error::binding::BindingError;
            use gaxi::path_parameter::PathMismatchBuilder;
            use gaxi::routing_parameter::Segment;
            let mut paths = Vec::new();
            {
                let builder = PathMismatchBuilder::default();
                let builder = builder.maybe_add(
                    Some(&req).map(|m| &m.bucket).map(|s| s.as_str()),
                    &[Segment::MultiWildcard],
                    "bucket",
                    "**",
                );
                paths.push(builder.build());
            }
            return Err(gax::error::Error::binding(BindingError { paths }));
        }

        type TR = crate::google::storage::v2::Object;
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, crate::model::Object>)
    }
}
